package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;


    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;

    @Override
    public List<JSONObject> getBaseCategoryList() {
//		创建一个JsonObject集合对象,用作返回的数据
        List<JSONObject> jsonObjects = new ArrayList<>();
//		查询出视图中的所有数据
        List<BaseCategoryView> baseCategoryViews = baseCategoryViewMapper.selectList(null);
//		根据一级目录的id去分组出所有的一级目录
        Map<Long, List<BaseCategoryView>> collect = baseCategoryViews.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
//		根据上面筛选出来的信息,获取其中map集合的相关目录
//		取出map中的所有键值对,并放到一个集合中
        Set<Map.Entry<Long, List<BaseCategoryView>>> entries = collect.entrySet();
//		遍历集合
        for (Map.Entry<Long, List<BaseCategoryView>> entry : entries) {
//			生成一个JSONObject对象
            JSONObject jsonObject = new JSONObject();
//			获取集合中键值对的key
            Long key = entry.getKey();
//			获取到集合中键值对中的value,因为value是list类型,因为以上集合是根据目录一的id去分组的,因此map的key值都一样,value是相同key的元素的集合
//			,又因为id1和name1的值一一对应因为我们取id对应的name的时候,就在mapvalue中随机找出一条数据获取name1就可以
            List<BaseCategoryView> value = entry.getValue();
//			对JSONOBJECT对象,添加键值对,第三个对象不着急封装,因为后面还要封装,这里先封装部分,后面再封装
            jsonObject.put("categoryId", key);
            jsonObject.put("categoryName", value.get(0).getCategory1Name());
//			根据第一次分组后获取到的value,按照二级目录id进行二次分组,对二级索引进行去重复
            Map<Long, List<BaseCategoryView>> collect1 = value.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
//			此时跟第一次分组一样,key是分组的字段,值是分组后具有相同分组字段属性值的bean集合
            Set<Map.Entry<Long, List<BaseCategoryView>>> entries1 = collect1.entrySet();
//			创建一个jsonobject对象用于之后去装一级目录下的所有二级目录
            List<JSONObject> jsonObjects1 = new ArrayList<>();
//			对二级目录获取到的数据进行遍历
            for (Map.Entry<Long, List<BaseCategoryView>> entry1 : entries1) {
//				创建一个jsonObject1 去封装二级目录内容
                JSONObject jsonObject1 = new JSONObject();
//				这里的封装跟一级目录一样,只是key值不同,因为是二级目录,因此key是二级目录的id,value是二级目录的name,赋值也都相同
                List<BaseCategoryView> value1 = entry1.getValue();
                jsonObject1.put("categoryId", entry1.getKey());
                jsonObject1.put("categoryName", value1.get(0).getCategory2Name());
//				这是创建一个新的jsonobject集合,用于封装三级目录
                List<JSONObject> jsonObjects2 = new ArrayList<>();
//				因为三级目录内容都不用重复,所以不需要去重复,因此直接遍历即可
                List<JSONObject> collect2 = value1.stream().map(item -> {
//					在遍历的时候创建一个jsonobject对象,封装三级目录内容
                    JSONObject jsonObject2 = new JSONObject();
//					将值都放进去
                    jsonObject2.put("categoryId", item.getCategory3Id());
                    jsonObject2.put("categoryName", item.getCategory3Name());
//					封装完三级目录后,将对应的jsonobject对象都放到jsonObjects2集合中
                    jsonObjects2.add(jsonObject2);
                    return jsonObject2;
                }).collect(Collectors.toList());
//				此时需要将jsonObject2集合封装到对应的jsonObject1对象中
                jsonObject1.put("categoryChild", jsonObjects2);
//				将jsonObject1对象放到jsonObjects1集合中
                jsonObjects1.add(jsonObject1);
            }
//			将jsonObject1集合放到jsonObject中
            jsonObject.put("categoryChild", jsonObjects1);
//			将其添加到jsonObjects集合中   因为数据对应的情况是,一个一级目录对应多个二级目录,一个二级目录对应多个三级目录,因此才需要一层一层的封装
            jsonObjects.add(jsonObject);
        }
//		将最后封装的到的数据进行返回
        return jsonObjects;
    }

    @Override
    public List<BaseAttribute> findAttribute(Long category1Id) {
//		调用mapper层方法
        return baseAttributeMapper.findAttribute(category1Id);
    }

    @Override
    public BaseCategoryView getCategoryInfo(Long category3Id) {
        BaseCategoryView baseCategoryView = baseCategoryViewMapper.selectById(category3Id);
        return baseCategoryView;
    }

    /**
     * 根据一级分类ID获取分类列表
     * 该方法重写自父类，用于获取与特定一级分类ID相关的所有分类信息
     * 它不仅返回一级分类的信息，还包括其下的二级和三级分类信息
     *
     * @param categoryId 一级分类的ID
     * @return 包含分类信息的JSONObject对象
     */
    @Override
    public JSONObject getBaseCategoryList(Long categoryId) {
        // 根据一级分类id查询出所有的分类数据(因为查的是试图,所以一级里面包含很多二级,二级里面包含很多三级)
        List<BaseCategoryView> baseCategoryViews = baseCategoryViewMapper.selectList(new LambdaQueryWrapper<BaseCategoryView>().eq(BaseCategoryView::getCategory1Id, categoryId));
        // 创建一个JSONobject对象
        JSONObject jsonObject = new JSONObject();
        if (baseCategoryViews != null) {
            // 获取并设置一级分类信息
            Long category1Id = baseCategoryViews.get(0).getCategory1Id();
            jsonObject.put("categoryId", category1Id);
            jsonObject.put("categoryName", baseCategoryViews.get(0).getCategory1Name());
            // 初始化用于存储二级分类的列表
            List<JSONObject> jsonObjects = new ArrayList<JSONObject>();
            if (baseCategoryViews.size() > 1) {
                // 将查询结果根据二级分类ID分组
                Map<Long, List<BaseCategoryView>> collect = baseCategoryViews.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
                Set<Map.Entry<Long, List<BaseCategoryView>>> entries = collect.entrySet();
                // 遍历每个二级分类
                for (Map.Entry<Long, List<BaseCategoryView>> entry : entries) {
                    JSONObject jsonObject1 = new JSONObject();
                    jsonObject1.put("categoryId", entry.getKey());
                    jsonObject1.put("categoryName", entry.getValue().get(0).getCategory2Name());
                    // 初始化用于存储三级分类的列表
                    List<JSONObject> jsonObjects1 = new ArrayList<>();
                    // 遍历并设置三级分类信息
                    entry.getValue().stream().forEach(item -> {
                        JSONObject jsonObject2 = new JSONObject();
                        jsonObject2.put("categoryId", item.getCategory3Id());
                        jsonObject2.put("categoryName", item.getCategory3Name());
                        jsonObjects1.add(jsonObject2);
                    });
                    jsonObject1.put("categoryChild", jsonObjects1);
                    jsonObjects.add(jsonObject1);
                }
            }
            jsonObject.put("categoryChild", jsonObjects);
        }
        return jsonObject;
    }

	/**
	 * 根据一级分类ID查找顶级三级分类
	 *
	 * @param category1Id 一级分类的ID
	 * @return 返回顶级三级分类的列表，如果找不到则返回null
	 */
	@Override
	public List<BaseCategory3> findTopBaseCategory3(Long category1Id) {
	    // 查询所有属于给定一级分类ID的二级分类
	    List<BaseCategory2> baseCategory2s = baseCategory2Mapper.selectList(new LambdaQueryWrapper<BaseCategory2>().eq(BaseCategory2::getCategory1Id, category1Id));

	    // 提取二级分类的ID到一个列表中
	    List<Long> collect = baseCategory2s.stream().map(baseCategory2 -> baseCategory2.getId()).collect(Collectors.toList());

	    // 初始化三级分类列表为null
	    List<BaseCategory3> list = null;

	    // 如果二级分类ID列表不为空，则查询所有属于这些二级分类的三级分类
	    if (!ObjectUtils.isEmpty(collect)){
	        list = baseCategory3Mapper.selectList(new LambdaQueryWrapper<BaseCategory3>().in(BaseCategory3::getCategory2Id, collect).last("limit 7"));
	    }

	    // 返回查询到的三级分类列表，可能为null
	    return list;
	}

    @Override
    public List<BaseCategory1> findAllCategory1() {
        return baseCategory1Mapper.selectList(null);
    }
}
